using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using METU_CMT.DataSets.METUCMTDataSetTableAdapters;
using METU_CMT.DataSets.SpecialQueriesTableAdapters;

namespace METU_CMT.Business
{
    public class CourseTableAdapter
    {
        public string GetCourseCode(int courseId)
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            DataTable _courses = _coursesTableAdapter.GetDataByCourseId(courseId);
            return _courses.Rows.Count != 1 ? string.Empty : _courses.Rows[0]["CourseCode"].ToString();
        }

        public string GetCourseName(int courseId)
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            DataTable _courses = _coursesTableAdapter.GetDataByCourseId(courseId);
            return _courses.Rows.Count != 1 ? string.Empty : _courses.Rows[0]["CourseName"].ToString();
        }

        public string GetCourseSemester(int courseId)
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            DataTable _courses = _coursesTableAdapter.GetDataByCourseId(courseId);
            return _courses.Rows.Count != 1 ? string.Empty : _courses.Rows[0]["Semester"].ToString();
        }

        public List<Announcement> GetAnnouncements(int courseId)
        {
            List<Announcement> _announcements = new List<Announcement>();
            AnnouncementsTableAdapter _announcementsTableAdapter = new AnnouncementsTableAdapter();
            DataTable _announcementsDt = _announcementsTableAdapter.GetDataByCourseId(courseId);

            foreach (DataRow _dataRow in _announcementsDt.Rows)
            {
                Announcement _announcement = new Announcement();
                DateTime _announcementTime;
                if (DateTime.TryParse(_dataRow["AnnouncementDate"].ToString(), out _announcementTime))
                {
                    _announcement.AnnouncementTime = _announcementTime;
                }
                else
                {
                    //TODO: Log: Time conversion problem
                }

                _announcement.Entry = _dataRow["Announcement"].ToString();
                _announcement.Subject = _dataRow["Subject"].ToString();
                _announcement.AnnouncementId = int.Parse(_dataRow["AnnouncementId"].ToString());

                _announcements.Add(_announcement);
            }

            return _announcements;
        }

        public List<Event> GetSchedule(int courseId)
        {
            EventsTableAdapter _scheduleAndEventsTableAdapter = new EventsTableAdapter();
            DataTable _eventsDt = _scheduleAndEventsTableAdapter.GetDataByCourseId( courseId );

            List<Event> _events = new List<Event>();

            foreach (DataRow _eventDr in _eventsDt.Rows)
            {
                int _eventId;
                if (int.TryParse(_eventDr["EventId"].ToString(), out _eventId) == false)
                {
                    continue;
                }
                Event _event = new Event(_eventId);
                _events.Add(_event);
            }
            return _events;
        }

        public List<Instructor> GetInstructors(int courseId)
        {
            CourseInstructorsTableAdapter _courseInstructorsTableAdapter = new CourseInstructorsTableAdapter();
            DataTable _instructorsDt = _courseInstructorsTableAdapter.GetDataByCourseId(courseId);

            List<Instructor> _instructors = new List<Instructor>();

            foreach (DataRow _instructorDr in _instructorsDt.Rows)
            {
                int _instructorId;
                if (int.TryParse(_instructorDr["UserId"].ToString(), out _instructorId) == false)
                {
                    continue;
                }

                DataSets.METUCMTDataSetTableAdapters.UsersTableAdapter _usersTableAdapter = new DataSets.METUCMTDataSetTableAdapters.UsersTableAdapter();

                if (_usersTableAdapter.GetDataByUserId(_instructorId).Rows[0]["Role"].ToString().CompareTo(
                    Resource.RInstructor) != 0)
                {
                    continue;
                }

                Instructor _instructor = new Instructor(_instructorId);
                _instructors.Add(_instructor);
            }

            return _instructors;
        }

        public List<Note> GetLectureNotes(int courseId)
        {
            LectureNotesTableAdapter _lectureNotesTableAdapter = new LectureNotesTableAdapter();
            DataTable _notesDt = _lectureNotesTableAdapter.GetDataByCourseId(courseId);

            List<Note> _notes = new List<Note>();
            foreach (DataRow _noteDr in _notesDt.Rows)
            {
                Note _note = new Note
                                 {
                                     NoteId = int.Parse(_noteDr["NoteId"].ToString()),
                                     File = _noteDr["SystemNoteName"].ToString(),
                                     Name = _noteDr["NoteName"].ToString()
                                 };

                DateTime _uploadTime;
                if (DateTime.TryParse(_noteDr["UploadTime"].ToString(), out _uploadTime))
                {
                    _note.UploadTime = _uploadTime;
                }
                else
                {
                    //TODO: Log: Time conversion problem
                }

                _notes.Add(_note);
            }

            return _notes;
        }

        public List<ReviewTeam> GetReviewTeams(int courseId)
        {
            CourseAndReviewTeamsTableAdapter _courseAndReviewTeamsTableAdapter = new CourseAndReviewTeamsTableAdapter();
            DataTable _reviewTeamsDt = _courseAndReviewTeamsTableAdapter.GetDataByCourseId( courseId );

            List<ReviewTeam> _reviewTeams = new List<ReviewTeam>();

            foreach (DataRow _reviewTeamDr in _reviewTeamsDt.Rows)
            {
                int _reviewTeamId;
                if (int.TryParse(_reviewTeamDr["ReviewTeamId"].ToString(), out _reviewTeamId) == false)
                {
                    continue;
                }
                ReviewTeam _reviewTeam = new ReviewTeam(_reviewTeamId);
                _reviewTeams.Add(_reviewTeam);
            }

            return _reviewTeams;
        }

        public List<TeachingAssistant> GetTas(int courseId)
        {
            //TODO: is the name correct??? for Teaching assistant use this table ????? important
            CourseInstructorsTableAdapter _courseTasTableAdapter = new CourseInstructorsTableAdapter();
            DataTable _instructorsDt = _courseTasTableAdapter.GetDataByCourseId(courseId);

            List<TeachingAssistant> _teachingAssistants = new List<TeachingAssistant>();

            foreach (DataRow _tadr in _instructorsDt.Rows)
            {
                int _taId;
                if (int.TryParse(_tadr["UserId"].ToString(), out _taId) == false)
                {
                    continue;
                }
                DataSets.METUCMTDataSetTableAdapters.UsersTableAdapter _usersTableAdapter = new DataSets.METUCMTDataSetTableAdapters.UsersTableAdapter(  );

                if( _usersTableAdapter.GetDataByUserId( _taId ).Rows[ 0 ][ "Role" ].ToString( ).CompareTo(
                    Resource.RTeachingAssistant ) != 0 )
                {
                    continue;
                }
                
                TeachingAssistant _teachingAssistant = new TeachingAssistant(_taId);
                _teachingAssistants.Add(_teachingAssistant);
            }

            return _teachingAssistants;
        }

        public List<Team> GetTeams(int courseId)
        {
            TeamsTableAdapter _teamsTableAdapter = new TeamsTableAdapter();
            DataTable _teamsDt = _teamsTableAdapter.GetDataByCourseId(courseId);

            List<Team> _teams = new List<Team>();

            foreach (DataRow _teamDr in _teamsDt.Rows)
            {
                int _teamId;
                if (int.TryParse(_teamDr["TeamId"].ToString(), out _teamId) == false)
                {
                    continue;
                }

                Team _team = new Team(_teamId);
                _teams.Add(_team);
            }
            return _teams;
        }

        public List<Student> GetStudents(int courseId)
        {
            CourseStudentTableAdapter _courseStudentsTableAdapter = new CourseStudentTableAdapter();
            DataTable _studentsDt = _courseStudentsTableAdapter.GetDataByCourseId(courseId);

            List<Student> _students = new List<Student>();

            foreach (DataRow _studentDr in _studentsDt.Rows)
            {
                int _studentId;
                if (int.TryParse(_studentDr["StudentId"].ToString(), out _studentId) == false)
                {
                    continue;
                }
                Student _student = new Student(_studentId);
                _students.Add(_student);
            }

            return _students;
        }

        public void InsertCourse(string courseName, string courseCode, string semester, out int courseId)
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            courseId = 0;
            var _courseId = (int?)courseId;
            int _success = _coursesTableAdapter.InsertCourse(courseCode, courseName, semester, ref _courseId);

            if (_courseId != null) courseId = (int)_courseId;
            if (_success < 1)
            {
                //TODO: Log: insert is not successfull.
            }
        }


        public void InsertInstructor(int courseId, Instructor instructor)
        {
            CourseInstructorsTableAdapter _courseInstructorsTableAdapter = new CourseInstructorsTableAdapter();
            _courseInstructorsTableAdapter.InsertCourseInstructor(courseId, instructor.UserId);
        }

        public void InsertStudent(int courseId, int insertedStudentId)
        {
            try
            {
                CourseStudentTableAdapter _courseStudentTableAdapter = new CourseStudentTableAdapter();
                _courseStudentTableAdapter.InsertCourseStudent(courseId, insertedStudentId);
            }
            catch (SqlException)
            {
                //TODO: throw new Exception( Resource.RTwiceRegistration );
            }
        }

        public void InsertTA(int courseId, int taId)
        {
            try
            {
                CourseInstructorsTableAdapter _courseInstructorsTableAdapter = new CourseInstructorsTableAdapter();
                _courseInstructorsTableAdapter.InsertCourseInstructor( courseId, taId );
            }
            catch (SqlException)
            {
                //TODO: throw new Exception( Resource.RTwiceRegistration );
            }
        }

        public void RemoveInstructor(int courseId, Instructor instructor)
        {
            //TODO: Not Implemented
        }

        public void RemoveStudent(int courseId, Student student)
        {
            //TODO: Not Implemented
        }

        public void RemoveTa(int courseId, int ta)
        {
            CourseInstructorsTableAdapter _courseStudentTableAdapter = new CourseInstructorsTableAdapter();
            _courseStudentTableAdapter.DeleteCourseInstructor( courseId, ta );
        }

        public void UpdateInstructor(int courseId, Instructor oldInstructor, Instructor newInstructor)
        {
            //TODO: Not Implemented
        }

        public void UpdateStudent(int courseId, Student oldStudent, Student newStudent)
        {
            //TODO: Not Implemented
        }

        public void UpdateTa(int courseId, TeachingAssistant oldTa, TeachingAssistant newTa)
        {
            //TODO: Not Implemented
        }

        public void InsertAnnouncement(int courseId, Announcement announcement, out int? announcementId)
        {
            AnnouncementsTableAdapter _announcementsTableAdapter = new AnnouncementsTableAdapter();
            announcementId = 0;
            _announcementsTableAdapter.InsertAnnouncement(courseId, announcement.Subject, announcement.Entry,
                                                           announcement.AnnouncementTime, ref announcementId);
        }

        public void InsertEvent(int courseId, Event @event)
        {
            EventsTableAdapter _eventsTableAdapter = new EventsTableAdapter();
            _eventsTableAdapter.InsertEvent( courseId, @event.DueDate, @event.Description,
                                             @event.SubmissionExist == true ? 1 : 0 );
        }

        public void InsertLectureNote(int courseId, Note note)
        {
            LectureNotesTableAdapter _lectureNotesTableAdapter = new LectureNotesTableAdapter();
            _lectureNotesTableAdapter.InsertLectureNote(note.File, note.Name, note.UploadTime, courseId);
        }

        public void InsertReviewerTeam( ReviewTeam reviewTeam)
        {
            try
            {
                ReviewTeamsTableAdapter _reviewTeamsTableAdapter = new ReviewTeamsTableAdapter();
                _reviewTeamsTableAdapter.InsertReviewTeam(reviewTeam.Event.EventId, reviewTeam.ReviewedTeam.TeamId,
                                                           reviewTeam.ReviewerTeam.TeamId);
            }
            catch (SqlException)
            {
            }
        }

        public void InsertTeam(int courseId, Team team)
        {
            TeamsTableAdapter _teamsTableAdapter = new TeamsTableAdapter();
            _teamsTableAdapter.InsertTeam(courseId, team.TeamName, team.LogoFile);
        }

        public void RemoveAnnouncement(int announcement)
        {
            AnnouncementsTableAdapter _announcementsTableAdapter = new AnnouncementsTableAdapter();
            _announcementsTableAdapter.DeleteAnnouncement(announcement);
        }

        public void RemoveEvent(int courseId, int @event)
        {
            EventsTableAdapter _eventsTableAdapter = new EventsTableAdapter(  );
            _eventsTableAdapter.DeleteEvent( @event );
        }

        public void RemoveLectureNote(int note)
        {
            LectureNotesTableAdapter _lectureNotesTableAdapter = new LectureNotesTableAdapter();
            _lectureNotesTableAdapter.DeleteLectureNote(note);
        }

        public void RemoveReviewerTeam(int reviewerTeam)
        {
            ReviewTeamsTableAdapter _reviewTeamsTableAdapter = new ReviewTeamsTableAdapter(  );
            _reviewTeamsTableAdapter.DeleteReviewTeam( reviewerTeam );
        }

        public void RemoveTeam(int courseId, Team team)
        {
            TeamsTableAdapter _teamsTableAdapter = new TeamsTableAdapter();
            _teamsTableAdapter.DeleteTeam(team.TeamId);
        }

        public void UpdateAnnouncement(int courseId, Announcement updatedAnnouncement)
        {
            AnnouncementsTableAdapter _announcementsTableAdapter = new AnnouncementsTableAdapter();
            _announcementsTableAdapter.UpdateAnnouncement(courseId, updatedAnnouncement.Subject,
                                                           updatedAnnouncement.Entry, updatedAnnouncement.AnnouncementId);
        }

        public void UpdateEvent(int courseId, int oldEvent, Event newEvent)
        {
            EventsTableAdapter _eventsTableAdapter = new EventsTableAdapter();
            _eventsTableAdapter.UpdateEvent(courseId, newEvent.DueDate, newEvent.Description,
                                            newEvent.SubmissionExist == true ? 1 : 0,
                                            oldEvent);
        }

        public void RemoveCourse(Course course)
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            _coursesTableAdapter.DeleteCourse(course.CourseId);
        }

        public void UpdateCourse(CourseInstructor oldcourse, CourseInstructor newCourse)
        {
            //TODO: Not Implemented
        }

        public void InsertCourse(Course courseName)
        {
            //TODO: Not Implemented
        }

        public void RemoveCourseInstructor(Course course, int userId)
        {
            CourseInstructorsTableAdapter _courseInstructorsTableAdapter = new CourseInstructorsTableAdapter();
            _courseInstructorsTableAdapter.DeleteCourseInstructor(course.CourseId, userId);
        }

        public void RemoveCourseStudent(int courseId, int studentId)
        {
            CourseStudentTableAdapter _courseStudentTableAdapter = new CourseStudentTableAdapter();
            _courseStudentTableAdapter.DeleteCourseStudent(courseId, studentId);
        }

        public List<Course> GetAllCourses()
        {
            CoursesTableAdapter _coursesTableAdapter = new CoursesTableAdapter();
            DataTable _coursesDt = _coursesTableAdapter.GetData();

            List<Course> _courses = new List<Course>();

            foreach (DataRow _courseDr in _coursesDt.Rows)
            {
                int _courseId;
                if (int.TryParse(_courseDr["CourseId"].ToString(), out _courseId) == false)
                {

                }
                Course _course = new Course(_courseId);
                _courses.Add(_course);
            }

            return _courses;
        }

        public void InsertTeamMember(int teamId, Student student)
        {
            TeamMembersTableAdapter _teamMembersTableAdapter = new TeamMembersTableAdapter();
            _teamMembersTableAdapter.InsertTeamMember(teamId, student.UserId);
        }
    }
}